/**
 * JAVACC DEMO 1.0
 * @copy right dwusoft company All rights reserved. 
 * @Package com.apache.uct.service.plugins  
 */
package com.apache.uct.service.plugins;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.omg.CORBA.UserException;

import com.apache.api.manager.PluginConnector;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.cache.util.Validator;
import com.apache.tools.TreeNode;
import com.apache.uct.common.entity.Act;
import com.apache.uct.common.entity.Dept;
import com.apache.uct.common.entity.User;
import com.apache.uct.manager.ActManager;
import com.apache.uct.manager.DeptManager;

/**
 * description:  工作流系统特殊操作处理类
 * @author dwusoft 创建时间：2015-4-3  
 * @Copyright(c)2014:北京--软件技术有限公司
 */
public class FlowCorePlugin implements PluginConnector {

	private Logger log = Logger.getLogger(FlowCorePlugin.class);
	private ActManager actManager;
	private DeptManager deptManager;
	private UserListPlugin userListPlugin;

	/**
	 * TODO 工作流系统特殊操作处理类.  <br>
	 * 参数说明:<br>
	 * methodType:方法标识(getUsersStr/getActTree)  必须;<br>
	 * actId:权限ID;<br>
	 * deptcross:取值类型(1,2,3,4);<br>
	 * deptId:部门ID
	 * fatherId:上级部门ID(可空)
	 */
	public Object execute(ParamsVo vo) throws Exception {
		//根据权限Id，是否跨部门，部门id获取用户
		//远程根据权限Id 部门Id  取值类型获取用户信息(暂时不提供)
		//远程根据系统获取该系统下的权限树
		log.info("工作流调用请求参数："+vo.getParams());
		ResultEntity result = new ResultEntity();
		try {
			String key = String.valueOf(vo.getParams("methodType"));
			result.setResult("true");
			if ("getUsersStr".equals(key)) {//根据权限Id，是否跨部门，部门id获取用户
				String actId = String.valueOf(vo.getParams("actId"));
				String roleId = String.valueOf(vo.getParams("roleId"));
				String deptcross = String.valueOf(vo.getParams("deptcross"));
				String deptId = String.valueOf(vo.getParams("deptId"));
				String users = getUsersStr(actId, deptcross, deptId, roleId);
				if (Validator.isNotNull(users)) {
					result.setMessage("获取用户成功");
				} else {
					result.setResult("false");
					result.setMessage("获取用户失败，或者没有查找到符合要求的用户");
				}
				result.setEntity(users);
			} else if ("getActTree".equals(key)) {//远程根据系统获取该系统下的权限树
				String fatherId = String.valueOf(vo.getParams("fatherId"));
				String isAll = String.valueOf(vo.getParams("isAll"));
				String sysEname = String.valueOf(vo.getParams("sysEname"));
				String jsonStr = getActTree(fatherId, isAll, sysEname);
				if (Validator.isNotNull(jsonStr)) {
					result.setMessage("获取权限成功");
					result.setEntity(jsonStr);
				} else {
					result.setResult("false");
					result.setMessage("获取权限失败");
				}
			} else {
				result.setResult("false");
				result.setMessage("没有找到待执行的方法！");
			}
			log.info("工作流调用[key="+key+"],从此插件获取的结果："+result.getEntity());
		} catch (Exception e) {
			result.setResult("false");
			log.error("执行查询失败 ", e);
			result.setMessage("查询失败！");
		}
		return result;
	}

	/**
	 * 根据权限Id，是否跨部门，部门id获取用户
	 * @return
	 */
	private String getUsersStr(String actId, String deptcross, String deptId, String roleId) {
		String users = this.getTaskUserIds(actId, deptcross, deptId, roleId);
		return users;
	}

	/*
	 * 远程根据权限Id 部门Id  取值类型获取用户信息
	 */
	private String getTaskUserIds(String actId, String deptcross, String deptId, String roleId) {
		StringBuffer taskUserIds = new StringBuffer("");
		ParamsVo vo = new ParamsVo();
		List<User> users = new ArrayList<User>();
		vo.setParams("actId", actId);
		vo.setParams("flowRoleId", roleId);
		try {
			if ("1".equals(deptcross)) {//部门内
				vo.setParams("deptId", deptId);
				users = this.getUserList(vo);
			} else {
				String orgId = "";
				if (Validator.isNotNull(deptId)) {
					ParamsVo<Dept> pvo = new ParamsVo<Dept>();
					pvo.setInfoId(deptId);
					Dept dept = (Dept) deptManager.getInfoById(pvo);
					// 通过角色获得用户
					if (!Validator.isEmpty(dept)) {
						orgId = dept.getOrgId();
					}
				}
				if ("2".equals(deptcross)) {//跨部门
					vo.setParams("orgId", orgId);
					vo.setParams("dataDeptId", deptId);//跨部门
					users = this.getUserList(vo);
				} else if ("3".equals(deptcross)) {//机构内
					vo.setParams("orgId", orgId);
					users = this.getUserList(vo);
				} else if ("4".equals(deptcross)) {//跨机构
					vo.setParams("dataOrgId", orgId);//跨机构任务:2
					users = this.getUserList(vo);
				}
			}
		} catch (UserException e) {
			e.printStackTrace();
		}
		if (!Validator.isEmpty(users)) {
			int count = users.size();
			for (int i = 0; i < count; i++) {
				User user = users.get(i);
				if (i == count - 1) {
					taskUserIds.append(user.getUserEname());
				} else {
					taskUserIds.append(user.getUserEname()).append(",");
				}
			}
		}
		return taskUserIds.toString();
	}

	/**
	 * 得到隶属某个部门并拥有某个操作权限的用户列表
	 */
	private List<User> getUserList(ParamsVo vo) throws UserException {
		try {
			ResultEntity result = (ResultEntity) userListPlugin.execute(vo);
			return (List<User>) result.getEntity();
		} catch (Exception e) {

		}
		return null;
	}

	/**
	 * 远程根据系统获取该系统下的权限树
	 * @return
	 */
	private String getActTree(String fatherId, String isAll, String sysEname) {
		net.sf.json.JSONArray jary = new net.sf.json.JSONArray();
		try {
			String fullEname = "";
			Act act = null;

			if (Validator.isNull(fatherId) && Validator.isNotNull(sysEname)) {
				fullEname = "/" + sysEname.trim();
				this.log.info("----fullEname-----" + fullEname);
				ParamsVo voFullEname = new ParamsVo();
				voFullEname.setParams("propertyName", "fullEname");
				voFullEname.setParams("propertyValue", fullEname);
				voFullEname.setKey("ByActProperty");
				act = (Act) actManager.execute(voFullEname);
				if (null == act) {
					this.log.error("-----根据[sysEname=" + sysEname + ";]查询数据失败!");
					return jary.toString();
				}
				fatherId = act.getActId();

			} else if (Validator.isNull(fatherId)) {
				this.log.error("-----缺少必要的参数：[sysEname][fatherId]!------");
				return jary.toString();
			}

			List<Act> list = getActsByFatherId(fatherId);

			for (int i = 0; i < list.size(); i++) {
				Act vo = list.get(i);
				if (Validator.isEmpty(vo))
					continue;
				TreeNode tvo = toTreeVo(vo);
				String voFullEname = Validator.getDefaultStr(vo.getFullEname(), "");

				if ("T".equals(isAll)) {//fatherId下完整树形数据
					tvo = getSubTree(tvo, vo, voFullEname);
					tvo.setState("opened");
				}
				jary.add(tvo);
			}
		} catch (Exception e) {
			e.printStackTrace();
			this.log.error("-----ErrorMessage------" + e.getMessage());
			return jary.toString();
		}

		return jary.toString();
	}

	/**
	 * 将Act转成程TreeNode
	 * @param vo
	 * @return TreeNode
	 */
	private TreeNode toTreeVo(Act vo) {
		TreeNode tvo = new TreeNode();
		tvo.setChecked("checked");
		tvo.setIconCls("");
		if (Validator.isEmpty(vo.getSubCount()))
			vo.setSubCount(0);
		if (vo.getSubCount() > 0) {
			tvo.setState("closed");
		} else {
			tvo.setState("opened");
		}
		tvo.setId(vo.getActId());
		tvo.setText(vo.getActCname());
		return tvo;
	}

	/**
	 * 递归查询所有子节点
	 * @param treeNode
	 * @param act
	 * @param fullEname
	 * @return TreeNode
	 */
	private TreeNode getSubTree(TreeNode treeNode, Act act, String fullEname) {
		List<Act> list = getActsByFatherId(act.getActId());
		List<TreeNode> children = new ArrayList<TreeNode>();
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				Act vo = list.get(i);
				if (Validator.isEmpty(vo))
					continue;
				TreeNode tvo = toTreeVo(vo);
				String voFullEname = Validator.getDefaultStr(vo.getFullEname(), "");
				if (voFullEname.startsWith(fullEname)) {
					tvo.setState("opened");
				}
				children.add(getSubTree(tvo, vo, fullEname));
			}
		}
		treeNode.setChildren(children);
		return treeNode;
	}

	private List<Act> getActsByFatherId(String actId) {
		ParamsVo<Act> vo = new ParamsVo<Act>();
		Act act = new Act();
		act.setFatherId(actId);
		vo.setObj(act);
		return actManager.getList(vo);
	}

	public void setActManager(ActManager actManager) {
		this.actManager = actManager;
	}

	public void setDeptManager(DeptManager deptManager) {
		this.deptManager = deptManager;
	}

	public void setUserListPlugin(UserListPlugin userListPlugin) {
		this.userListPlugin = userListPlugin;
	}

}
